package com.example.demo.quartz.service;

import java.util.List;

import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.entity.base.PageRequestBean;
import com.example.demo.entity.base.PageResponseBean;
import com.example.demo.entity.base.ResponseEntity;
import com.example.demo.entity.quartz.QuartzEntity;
import com.example.demo.quartz.dao.QuartzManagerDao;
import com.example.demo.util.CommonUtil;
import com.example.demo.util.EmptyUtil;
import com.example.demo.util.ResponseFactory;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

@Service
@Transactional(readOnly=true)
public class QuartzManagerService {
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private QuartzManagerDao quartzManagerDao;

    @Autowired @Qualifier("scheduler")
    private Scheduler scheduler;
    
    /**
     * 
     * @author 许子文
     * @Title: addJob
     * @Description: 新增定时任务
     * @param quartz
     * @return
     *
     */
    public ResponseEntity<String> addJob(QuartzEntity quartz){
    	String operationType = "新增";
    	
		try {
			//获取Scheduler实例、废弃、使用自动注入的scheduler、否则spring的service将无法注入
	        //Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
	        //如果是修改  展示旧的 任务
	        if(EmptyUtil.isNotEmpty(quartz.getOldJobGroup())){
	        	JobKey key = new JobKey(quartz.getOldJobName(),quartz.getOldJobGroup());
	        	scheduler.deleteJob(key);
	        	operationType = "修改";
	        }
	        Class cls = Class.forName(quartz.getJobClassName()) ;
	        cls.newInstance();
	        //构建job信息
	        JobDetail job = JobBuilder.newJob(cls).withIdentity(quartz.getJobName(),
	        		quartz.getJobGroup())
	        		.withDescription(quartz.getDescription()).build();
            job.getJobDataMap().put("jobMethodName", quartz.getJobMethodName());
	        // 触发时间点
	        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartz.getCronExpression());
	        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger"+quartz.getJobName(), quartz.getJobGroup())
	                .startNow().withSchedule(cronScheduleBuilder).build();	
	        //交由Scheduler安排触发
	        scheduler.scheduleJob(job, trigger);
		} catch (Exception e) {
			logger.error("{}任务失败",operationType,e);
			return ResponseFactory.setFail(operationType+"任务失败");
		}
		return ResponseFactory.setSuccess(operationType+"任务成功");
	}
    
    /**
     * 
     * @author 许子文
     * @Title: trigger
     * @Description: 单次调用任务
     * @param quartz
     * @return
     *
     */
    public ResponseEntity<String> trigger(QuartzEntity quartz) {
		try {
			JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
			scheduler.triggerJob(key);
		} catch (SchedulerException e) {
			logger.error("单次调用任务失败",e);
			return ResponseFactory.setFail("单次调用任务失败");
		}
		return ResponseFactory.setSuccess("单次调用任务成功");
	}
    
    /**
     * 
     * @author 许子文
     * @Title: pause
     * @Description: 暂停任务
     * @param quartz
     * @param response
     * @return
     *
     */
    public ResponseEntity<String> pause(QuartzEntity quartz) {
		try {
		     JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
		     scheduler.pauseJob(key);
		} catch (SchedulerException e) {
			logger.error("暂停任务失败",e);
			return ResponseFactory.setFail("暂停任务失败");
		}
		return ResponseFactory.setSuccess("暂停任务成功");
	}
    
    /**
     * 
     * @author 许子文
     * @Title: resume
     * @Description: 恢复定时任务运行
     * @param quartz
     * @return
     *
     */
    public ResponseEntity<String> resume(QuartzEntity quartz) {
		try {
		    JobKey key = new JobKey(quartz.getJobName(),quartz.getJobGroup());
		    scheduler.resumeJob(key);
		} catch (SchedulerException e) {
			logger.error("恢复任务运行失败",e);
			return ResponseFactory.setFail("恢复任务运行失败");
		}
		return ResponseFactory.setSuccess("恢复任务运行成功");
	}
    
    /**
     * 
     * @author 许子文
     * @Title: remove
     * @Description: 删除定时任务
     * @param quartz
     * @return
     *
     */
    public ResponseEntity<String> remove(QuartzEntity quartz) {
		try {  
            TriggerKey triggerKey = TriggerKey.triggerKey(quartz.getJobName(), quartz.getJobGroup());  
            // 停止触发器  
            scheduler.pauseTrigger(triggerKey);  
            // 移除触发器  
            scheduler.unscheduleJob(triggerKey);  
            // 删除任务  
            scheduler.deleteJob(JobKey.jobKey(quartz.getJobName(), quartz.getJobGroup()));  
            logger.info("removeJob:"+JobKey.jobKey(quartz.getJobName()));  
        } catch (Exception e) {  
        	logger.error("删除定时任务失败",e);
			return ResponseFactory.setFail("删除定时任务失败");
        }  
		return ResponseFactory.setSuccess("删除定时任务成功");
	}
	
	/**
	 * 
	 * @author 许子文
	 * @Title: queryQuartzJobList
	 * @Description: 查询定时任务列表
	 * @param pagerequest
	 * @return
	 *
	 */
	public ResponseEntity<PageResponseBean<QuartzEntity>> queryQuartzJobList(PageRequestBean<QuartzEntity> pagerequest) {
		ResponseEntity<PageResponseBean<QuartzEntity>> ret = new ResponseEntity<>();
		
		int pageNum = pagerequest.getPageNum();
		int pageSize = pagerequest.getPageSize();
		
		QuartzEntity params = pagerequest.getParams();
		
		if(null==params) {
			params = new QuartzEntity();
		}
		
		Page<QuartzEntity> page = PageHelper.startPage(pageNum, pageSize, true);
		
		List<QuartzEntity> quartzJobs = null;
		
		try {
			quartzJobs = quartzManagerDao.queryQuartzJobList(params);
		} catch (Exception e) {
			logger.error("分页查询定时任务列表失败",e);
			return ResponseFactory.setFail("分页查询定时任务列表失败");
		}
		
		if(EmptyUtil.isNotEmpty(quartzJobs)) {
			for (QuartzEntity quartzEntity : quartzJobs) {
				JobKey key = new JobKey(quartzEntity.getJobName(),quartzEntity.getJobGroup());
				try {
					JobDetail jobDetail = scheduler.getJobDetail(key);
					quartzEntity.setJobMethodName(jobDetail.getJobDataMap().getString("jobMethodName"));
				} catch (SchedulerException e) {
					logger.error("获取{}定时器执行的方法失败",quartzEntity.getJobName(),e);
				}
			}
		}
		
		long total = page.getTotal();
		
		int totalPages;
		
		try {
			totalPages = CommonUtil.getTotalPages(pageSize, total);
		} catch (Exception e) {
			logger.error("获取总页数时失败",e);
			return ResponseFactory.setFail("获取总页数时失败");
		}
		
		PageResponseBean<QuartzEntity> pageresp = new PageResponseBean<>(total, pageSize, pageNum, totalPages, quartzJobs);
		
		return ResponseFactory.setObject(pageresp);
	}
}
